# ************ main rules *******************

.PHONY: all debug library clean documentation install uninstall

all: library
	@echo -e $(cyan)build successfully executed$(plain)

library: build-library
	@echo -e $(cyan)shared library build successfully executed$(plain)

clean: clean-includedir clean-libdir clean-bindir clean-graphdir clean-docdir
	@echo -e $(cyan)clean successfully executed$(plain)
	
documentation: source-documentation latex-documentation
	@echo -e $(cyan)documentation built. Consult $(DOCDIR)sourceDocumentation.html for source documentation or $(DOC)YaoolaGuide.pdf for the language one.$(plain)
	
install:
	#TODO yet to be implemented -.-'
	@echo "YAOOLA is successfully installed in your computer! Way to go!"

uninstall:
	#TODO yet to be implemented -.-'
	@echo "YAOOLA has been successfully unistalled from your computer!"

# ************ macro definition **************

#destination directory containing all the header link files
IDIR=include/
#directory where all the external header files needed are store
EIDIR=externalInclude/
#directory containing the source documentation
DOCDIR=doc/
#directory containing the .o files
OBJDIR=obj/
#directory containing the .so or the executables files
BINDIR=bin/
#insert here every folder which holds at least a header file or a source file of the compiler (no tests here!). A source folder CANNOT contain another source folder!
directories=src classtable labeltable

#directory containing the .c files which will generate executables tests
testdirectories=tests
#directory containing all the .c files which will generate the very executable binaries
exedirectories=main
#variable representing all the header files contained in "directories" variable
headers=$(foreach directory,$(directories),$(wildcard $(directory)/*.h))
#variable representing all the c files contained in the "directories" variable
cfiles=$(foreach directory,$(directories),$(wildcard $(directory)/*.c))
#variable representing all the c files contained in the "testdirectories" variable
testfiles=$(foreach directory,$(testdirectories),$(wildcard $(directory)/*.c))
#variable representing all the c files contained in the "exedirectories" variable
exefiles=$(foreach directory,$(exedirectories),$(wildcard $(directory)/*.c))
#the compiler to use to compile the .c and .h files
CC=gcc
#additional flags used to compile only the .c files (not the executables ones!)
CFLAGS=-Wall -c -I$(IDIR) -I$(EIDIR)
#compiler option to use to compile the program in "debugging" mode
DEBUG=
#additional flag used when compiling separated object files (.o)
OBJLIBFLAG=
#additional flag used when compiling exes
EXELIBFLAG=

cyan='\e[0;36m'
yellow='\e[1;33m'
plain='\e[0m'

#************** PHONY targets *****************************

.PHONY: check-basename-installed
.PHONY: check-bison-installed
.PHONY: check-doxygen-installed
.PHONY: check-flex-installed
.PHONY: check-latex-installed

.PHONY: build-library
.PHONY: activate-debug-mode
.PHONY: activate-library-mode
#TODO inserire gli altri PHONY

#************* rules for finding whenever a program is installed or not ************

check-flex-installed:
	@echo -e $(cyan)'checking if the package "flex" is installed. Not installed? You can "sudo apt-get install flex"'$(plain)
	@which flex > /dev/null
check-doxygen-installed:
	@echo -e $(cyan)'checking if the package "doxygen" is installed. Not installed? You can download it from http://www.stack.nl/~dimitri/doxygen/download.html'$(plain)
	@which doxygen>/dev/null
check-basename-installed:
	@echo -e $(cyan)'checking if the command "basename" is installed. Not installed? You must have it installed in your system!'$(plain)
	@which basename>/dev/null
check-latex-installed:
	@echo -e $(cyan)'checking if the command "pdflatex" is installed. Not installed? You can "sudo apt-get install texlive"'$(plain)
	@which pdflatex>/dev/null
check-bison-installed:
	@echo -e $(cyan)'checking if the command "bison" is installed. Not Installed? You can do "sudo apt-get install bison"'$(plain)
	@which bison>/dev/null
check-mkdir-installed:
	@echo -e $(cyan)'checking if command "mkdir" is installed.'$(plain)
	@which bison>/dev/null

# ************* subrules *******************

build-library: activate-library-mode activate-debug-mode build-headers build-c-files build-exe-files
	@echo -e $(cyan)generating shared library...$(plain)
	@for exefile in $(exefiles); do\
		echo "$(CC) $(DEBUG) $(EXELIBFLAG) -o $(BINDIR)lib`basename $$exefile .c`.so $(wildcard $(OBJDIR)*.o)";\
		$(CC) $(DEBUG) $(EXELIBFLAG) -o $(BINDIR)lib`basename $$exefile .c`.so $(wildcard $(OBJDIR)*.o);\
	done

activate-debug-mode:
	$(eval DEBUG = -g)
	
activate-library-mode:
	$(eval OBJLIBFLAG=-fPIC)
	$(eval EXELIBFLAG=-shared)

source-documentation: check-doxygen-installed
	@echo -e $(cyan)generating source code documentation...$(plain)
	doxygen CustomProgrammingLanguage.doxyfile

latex-documentation: check-latex-installed
	@echo -e $(cyan)generating yaoola documentation...$(plain)
	cd $(DOCDIR)latex/src; \
	pdflatex YaoolaGuide; \
	rm *.aux *.toc *.log; \
	mv YaoolaGuide.pdf ../../.; \

main-directories: check-mkdir-installed
	@echo -e $(cyan)checking project file system...$(plain)
	mkdir -p $(BINDIR)
	mkdir -p $(OBJDIR)
	
build-headers: check-basename-installed
	@echo -e $(cyan)linking to headers...$(plain)
	@for header in $(headers); do\
		echo "ln -f -s -T ../$$header $(IDIR)`basename $$header`";\
		ln -f -s -T ../$$header $(IDIR)`basename $$header`;\
	done

#builds all the files stored in "exedirectories" folders
build-exe-files: check-basename-installed
	@echo -e $(cyan)building all the c exe files...$(plain)
	@for cfile in $(exefiles); do\
		echo "$(CC) $(DEBUG) $(OBJLIBFLAG) -o $(OBJDIR)`basename $$cfile .c`.o $$cfile $(CFLAGS)";\
		$(CC) $(DEBUG) $(OBJLIBFLAG) -o $(OBJDIR)`basename $$cfile .c`.o $$cfile $(CFLAGS);\
	done

#build all the support files to compile the compiler (so no tests or exes or mains)
build-c-files: lexer.h parser.h build-normal-c-files lexer.o parser.o


build-normal-c-files: check-basename-installed
	@echo -e $(cyan)building all the c files...$(plain)
	@for cfile in $(cfiles); do\
		echo "$(CC) $(DEBUG) $(OBJLIBFLAG) -o $(OBJDIR)`basename $$cfile .c`.o $$cfile $(CFLAGS)";\
		$(CC) $(DEBUG) $(OBJLIBFLAG) -o $(OBJDIR)`basename $$cfile .c`.o $$cfile $(CFLAGS);\
	done

parser.h:
	bison -vd -o src/parser.c src/parser.y
	mv src/parser.h $(IDIR)parser.h

lexer.h:
	flex -o src/lexer.c src/lexer.lex
	mv lexer.h $(IDIR)lexer.h

lexer.o: check-flex-installed parser.h
	$(CC) $(DEBUG) $(OBJLIBFLAG) $(CFLAGS) -o $(OBJDIR)lexer.o src/lexer.c
	rm src/lexer.c
	
parser.o: check-bison-installed parser.h
	$(CC) $(DEBUG) $(OBJLIBFLAG) $(CFLAGS) -o $(OBJDIR)parser.o src/parser.c
	rm src/parser.c

clean-libdir:
	rm -f $(OBJDIR)*

clean-bindir:
	rm -f $(BINDIR)*

clean-includedir:
	rm -f $(IDIR)*
	
clean-graphdir:
	rm -f grp/*

clean-docdir:
	rm -f doc/html/*	